/**
  ******************************************************************************
  * @author     Chris
  * @since      2024/6/21 18:16
  *
  * @file       pd_i2c.h
  * @brief      Header file of I2C peripheral driver.
  *
  * @note       This file contains the I2C object declaration.
  *
  * @warning    None.
  ******************************************************************************
  * Change Logs:
  *   Date          Author       Notes
  *   2024/6/21     Chris        the first version
  *
  ******************************************************************************
  */


#ifndef JLC_SKY_I2C_H
#define JLC_SKY_I2C_H

#include "stm32f407xx.h"
#include "pd_gpio.h"

struct I2CVtbl;

// Object properties
typedef struct {
    GPIO *sck;
    GPIO *sda;

    struct I2CVtbl *vptr;
} I2C;

// Object virtual table
struct I2CVtbl {
    void (*init)(const I2C *this);

    uint8_t (*send)(const I2C *this, uint8_t salveAddress, uint16_t regAddress, uint8_t *dat, uint8_t len);

    uint8_t (*read)(const I2C *this, uint8_t salveAddress, uint16_t regAddress, uint8_t *dat, uint8_t len);
};

// Object constructor and member function
void I2C_constructor(I2C *this, GPIO *sck, GPIO *sda);

static inline void I2C_init(const I2C *this) {
    this->vptr->init(this);
}

static inline uint8_t I2C_send(const I2C *this, const uint8_t salveAddress, const uint16_t regAddress,
                               uint8_t *dat, const uint8_t len) {
    return this->vptr->send(this, salveAddress, regAddress, dat, len);
}

static inline uint8_t I2C_read(const I2C *this, const uint8_t salveAddress, const uint16_t regAddress,
                               uint8_t *dat, const uint8_t len) {
    return this->vptr->read(this, salveAddress, regAddress, dat, len);
}

#endif //JLC_SKY_I2C_H
